home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 10 / Example 10.1 / player.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-06-30  |  7.6 KB  |  293 lines

  1. #include "player.h"        
  2.  
  3. //Player Shaders
  4. SHADER lighting, teamCol;
  5. D3DXHANDLE worldHandle, viewProjHandle, sunHandle, teamColHandle, vertexCol, mapSizeHandle;
  6. ID3DXLine *selLine = NULL;
  7.  
  8. void LoadPlayerResources(IDirect3DDevice9* Device)
  9. {
  10.     //Setup shaders
  11.     lighting.Init(Device, "shaders/lighting.vs", VERTEX_SHADER);
  12.     worldHandle = lighting.GetConstant("matW");
  13.     viewProjHandle = lighting.GetConstant("matVP");
  14.     sunHandle = lighting.GetConstant("DirToSun");
  15.     vertexCol = lighting.GetConstant("vertexCol");
  16.     mapSizeHandle = lighting.GetConstant("mapSize");
  17.  
  18.     teamCol.Init(Device, "shaders/teamCol.ps", PIXEL_SHADER);
  19.     teamColHandle = teamCol.GetConstant("tmCol");
  20.  
  21.     //Line for unit selection
  22.     D3DXCreateLine(Device, &selLine);
  23. }
  24.  
  25. void UnloadPlayerResources()
  26. {
  27.     if(selLine != NULL)
  28.         selLine->Release();
  29.     selLine = NULL;
  30. }
  31.  
  32. //////////////////////////////////////////////////////////////////////////////////
  33. //                                PLAYER                                            //
  34. //////////////////////////////////////////////////////////////////////////////////
  35.  
  36. PLAYER::PLAYER(int _teamNo, D3DXVECTOR4 _teamCol, INTPOINT startPos, TERRAIN* _terrain, IDirect3DDevice9* _Device)
  37. {
  38.     m_teamNo = _teamNo;
  39.     m_teamColor = _teamCol;
  40.     m_pTerrain = _terrain;
  41.     m_pDevice = _Device;
  42.     m_areaSelect = false;
  43.  
  44.     if(m_pTerrain == NULL)return;
  45.  
  46.     //Add a few buildings
  47.     for(int i=0;i<3;i++)
  48.     {
  49.         INTPOINT p = FindClosestBuildingLocation(i, startPos);
  50.  
  51.         if(m_pTerrain->Within(p))
  52.             AddMapObject(i, p, true);
  53.     }
  54.  
  55.     //Also add a few units
  56.     for(int i=0;i<6;i++)
  57.     {
  58.         INTPOINT mp;
  59.         bool ok = false;
  60.         do
  61.         {
  62.             mp.x = rand()%20 - 10 + startPos.x;
  63.             mp.y = rand()%20 - 10 + startPos.y;
  64.  
  65.             MAPTILE *tile = m_pTerrain->GetTile(mp);
  66.             if(tile != NULL)ok = tile->m_walkable && tile->m_pMapObject == NULL;
  67.         }
  68.         while(!ok);
  69.  
  70.         AddMapObject(i % 3, mp, false);
  71.     }
  72. }
  73.  
  74. PLAYER::~PLAYER()
  75. {
  76.     for(int i=0;i<m_mapObjects.size();i++)
  77.         if(m_mapObjects[i] != NULL)
  78.             delete m_mapObjects[i];
  79. }
  80.  
  81. void PLAYER::AddMapObject(int type, INTPOINT mp, bool isBuilding)
  82. {
  83.     if(isBuilding)
  84.         m_mapObjects.push_back(new BUILDING(type, m_teamNo, mp, m_pTerrain, true, m_pDevice));
  85.     else m_mapObjects.push_back(new UNIT(type, m_teamNo, mp, m_pTerrain, m_pDevice));
  86. }
  87.  
  88. void PLAYER::RenderMapObjects(CAMERA &camera)
  89. {
  90.     D3DXMATRIX identity;
  91.     D3DXMatrixIdentity(&identity);
  92.     
  93.     lighting.SetMatrix(viewProjHandle, camera.GetViewMatrix() * camera.GetProjectionMatrix());
  94.  
  95.     //Sun direction
  96.     D3DXVECTOR3 sun;
  97.     D3DXVec3Normalize(&sun, &D3DXVECTOR3(0.5f, 1.0f, -0.5));
  98.     lighting.SetVector3(sunHandle, sun);
  99.     lighting.SetVector3(mapSizeHandle, D3DXVECTOR3(m_pTerrain->m_size.x, m_pTerrain->m_size.y, 0.0f));
  100.  
  101.     //Team color
  102.     teamCol.SetVector4(teamColHandle, m_teamColor);
  103.     
  104.     //Fog-Of-War
  105.     m_pDevice->SetTexture(1, m_pTerrain->m_pFogOfWarTexture);
  106.  
  107.     //Vertex color
  108.     lighting.SetVector4(vertexCol, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f));
  109.  
  110.     lighting.Begin();
  111.     teamCol.Begin();
  112.  
  113.     //Render units
  114.     for(int i=0;i<m_mapObjects.size();i++)
  115.         if(m_mapObjects[i] != NULL)
  116.             if(!camera.Cull(m_mapObjects[i]->GetBoundingBox()))
  117.             {
  118.                 if(m_mapObjects[i]->m_isBuilding)
  119.                     lighting.SetMatrix(worldHandle, m_mapObjects[i]->GetWorldMatrix());
  120.                 else lighting.SetMatrix(worldHandle, identity);
  121.  
  122.                 m_mapObjects[i]->Render();
  123.             }
  124.  
  125.     teamCol.End();
  126.     lighting.End();
  127. }
  128.  
  129. void PLAYER::PaintSelectedMapObjects(CAMERA &camera)
  130. {
  131.     //Paint selected map objects
  132.     for(int i=0;i<m_mapObjects.size();i++)
  133.         if(m_mapObjects[i] != NULL)
  134.             if(!camera.Cull(m_mapObjects[i]->GetBoundingBox()))
  135.                 m_mapObjects[i]->PaintSelected();
  136. }
  137.  
  138. void PLAYER::UpdateMapObjects(float deltaTime)
  139. {
  140.     for(int i=0;i<m_mapObjects.size();i++)
  141.         if(m_mapObjects[i] != NULL)
  142.             m_mapObjects[i]->Update(deltaTime);
  143. }
  144.  
  145. INTPOINT PLAYER::FindClosestBuildingLocation(int buildType, INTPOINT mp)
  146. {
  147.     //i = Search Radius
  148.     for(int i=0;i<30;i++)
  149.     {
  150.         for(int x=mp.x - i;x<=mp.x + i;x++)
  151.         {
  152.             if(PlaceOk(buildType, INTPOINT(x, mp.y - i), m_pTerrain))return INTPOINT(x, mp.y - i);
  153.             if(PlaceOk(buildType, INTPOINT(x, mp.y + i), m_pTerrain))return INTPOINT(x, mp.y + i);
  154.         }
  155.  
  156.         for(int y=mp.y - i;y<=mp.y + i;y++)
  157.         {
  158.             if(PlaceOk(buildType, INTPOINT(mp.x - i, y), m_pTerrain))return INTPOINT(mp.x - i, y);
  159.             if(PlaceOk(buildType, INTPOINT(mp.x + i, y), m_pTerrain))return INTPOINT(mp.x + i, y);
  160.         }
  161.     }
  162.  
  163.     //No good place found
  164.     return INTPOINT(-1, -1);
  165. }
  166.  
  167. void PLAYER::Select(MOUSE &mouse)
  168. {
  169.     try
  170.     {
  171.         if(mouse.ClickLeft())    // If the mouse button is pressed
  172.         {                
  173.             for(int i=0;i<m_mapObjects.size();i++)    //Deselect all m_mapObjects
  174.                 m_mapObjects[i]->m_selected = false;
  175.  
  176.             if(!m_areaSelect)        // If no area selection is in progress
  177.             {    
  178.                 //Find closest m_mapObjects
  179.                 int mapObject = -1;
  180.                 float bestDist = 100000.0f;
  181.  
  182.                 D3DXMATRIX world;
  183.                 D3DXMatrixIdentity(&world);
  184.                 m_pDevice->SetTransform(D3DTS_WORLD, &world);
  185.                 RAY ray = mouse.GetRay();
  186.  
  187.                 for(int i=0;i<m_mapObjects.size();i++)
  188.                 {                    
  189.                     float dist = ray.Intersect(m_mapObjects[i]->GetBoundingBox());
  190.  
  191.                     if(dist >= 0.0f && dist < bestDist)
  192.                     {
  193.                         mapObject = i;
  194.                         bestDist = dist;
  195.                     }
  196.                 }
  197.                 if(mapObject > -1)
  198.                     m_mapObjects[mapObject]->m_selected = true;
  199.                 else
  200.                 {
  201.                     m_areaSelect = true;        // if no unit if found,                                             
  202.                     m_startSel = mouse;        // start area selection
  203.                 }
  204.             }
  205.             else    //Area Selection in progress
  206.             {
  207.                 // Create area rectangle
  208.                 INTPOINT p1 = m_startSel, p2 = mouse;
  209.                 if(p1.x > p2.x){int temp = p2.x;p2.x = p1.x;p1.x = temp;}
  210.                 if(p1.y > p2.y){int temp = p2.y;p2.y = p1.y;p1.y = temp;}
  211.                 RECT selRect = {p1.x, p1.y, p2.x, p2.y};
  212.  
  213.                 //Draw selection rectangle
  214.                 D3DXVECTOR2 box[] = {D3DXVECTOR2(p1.x, p1.y), D3DXVECTOR2(p2.x, p1.y), 
  215.                                      D3DXVECTOR2(p2.x, p2.y), D3DXVECTOR2(p1.x, p2.y), 
  216.                                      D3DXVECTOR2(p1.x, p1.y)};
  217.  
  218.                 selLine->SetWidth(1.0f);
  219.                 selLine->Begin();
  220.                 selLine->Draw(box, 5, 0xffffffff);                
  221.                 selLine->End();
  222.  
  223.                 //Select any units inside our rectangle
  224.                 for(int i=0;i<m_mapObjects.size();i++)
  225.                     if(m_mapObjects[i] != NULL && !m_mapObjects[i]->m_isBuilding)
  226.                     {
  227.                         INTPOINT p = GetScreenPos(m_mapObjects[i]->m_position, m_pDevice);
  228.                         if(p.inRect(selRect))m_mapObjects[i]->m_selected = true;
  229.                     }
  230.             }
  231.         }
  232.         else if(m_areaSelect)        //Stop area selection
  233.             m_areaSelect = false;
  234.  
  235.     }
  236.     catch(...)
  237.     {
  238.         debug.Print("Error in PLAYER::Select()");
  239.     }
  240. }
  241.  
  242. void PLAYER::UnitOrders(MOUSE &mouse)
  243. {
  244.     if(mouse.ClickRight())
  245.     {
  246.         mouse.DisableInput(300);
  247.  
  248.         for(int i=0;i<m_mapObjects.size();i++)
  249.             if(m_mapObjects[i] != NULL)
  250.                 if(!m_mapObjects[i]->m_isBuilding && m_mapObjects[i]->m_selected)
  251.                 {
  252.                     //Cast to UNIT
  253.                     UNIT *unit = (UNIT*)m_mapObjects[i];
  254.                     unit->Goto(mouse.m_mappos, false, true);
  255.                 }
  256.     }
  257. }
  258.  
  259. INTPOINT PLAYER::GetCenter()
  260. {
  261.     INTPOINT p;
  262.  
  263.     for(int i=0;i<m_mapObjects.size();i++)
  264.         if(m_mapObjects[i] != NULL)
  265.             p += m_mapObjects[i]->m_mappos;
  266.  
  267.     p /= m_mapObjects.size();
  268.  
  269.     return p;
  270. }
  271.  
  272. void PLAYER::IsMapObjectsVisible()
  273. {
  274.     for(int i=0;i<m_mapObjects.size();i++)
  275.         if(m_mapObjects[i] != NULL)
  276.         {
  277.             if(m_mapObjects[i]->m_isBuilding)
  278.             {
  279.                 RECT r = m_mapObjects[i]->GetMapRect(0);
  280.                 m_mapObjects[i]->m_visible = false;
  281.  
  282.                 for(int y=r.top;y<=r.bottom && !m_mapObjects[i]->m_visible;y++)
  283.                     for(int x=r.left;x<=r.right && !m_mapObjects[i]->m_visible;x++)
  284.                         if(m_pTerrain->m_pVisitedTiles[x + y * m_pTerrain->m_size.x])
  285.                             m_mapObjects[i]->m_visible = true;
  286.             }
  287.             else 
  288.             {
  289.                 INTPOINT mp = m_mapObjects[i]->m_mappos;
  290.                 m_mapObjects[i]->m_visible = m_pTerrain->m_pVisibleTiles[mp.x + mp.y * m_pTerrain->m_size.x];
  291.             }
  292.         }
  293. }